<?php
namespace App\Jobs;

use App\Models\AdminBill;
use App\Models\Group;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use App\Models\AdminProfitReport;

class DividendJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $order;

    protected $balance = 0;

    protected $device = null;

    protected $deviceGroup = null;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        //
        $this->order = $order;
        $this->balance = $this->order->paid_price;
        $this->device = $this->order->device;
        $this->deviceGroup = $this->device->group;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // 订单未分成
        if ($this->order->dividend !== 'NO' && $this->order->status === 'COMPLETE') {
            return false;
        }
        $this->computeByDeviceOrder();
        $this->computeByDeviceGroup();
        DB::transaction(function () {
            if ($this->balance < 1) {
                $this->orderDiviend();
            } else {
                // 像终端伙伴分成
                $this->merchantDiviend();
                // 给分销商分成
                $this->distributorDiviend();

                $this->agentDiviend();
                $this->orderDiviend();
            }
        });
    }

    public function computeByDeviceOrder()
    {
        $deviceOrder = $this->device->order;
        // 计算动态分润
        $scale = $deviceOrder->before_profit;
        if ($deviceOrder->total_sales_amount >= $deviceOrder->cost_total_price) {
            $scale = $deviceOrder->after_profit;
        }
        $this->balance = intval($this->balance * ($scale / 10000));
    }

    public function computeByDeviceGroup()
    {
        $this->balance = intval($this->balance * $this->deviceGroup->dividend_scale / 10000);
    }

    public function orderDiviend()
    {
        $this->order->dividend = 'YES';
        $this->order->save();
    }

    public function agentDiviend()
    {
        if ($this->balance < 1) {
            return false;
        }
        $agent = $this->deviceGroup->author;
        $agent->wallet->increment('balance', $this->balance);
        $this->balance = 0;
        $agentBill = [
            'origin_order_id'=>$this->order->id,
            'user_id' => $agent->id,
            'fee' => $this->balance,
            'type' => 'INPUT',
            'channel' => $this->order->channel,
            'remark' => '订单分成'
        ];
        // 收入统计
        $profitReport = AdminProfitReport::firstOrCreate(['user_id'=>$agent->id]);
        $profitReport->increment('amount',$this->balance);
        AdminBill::create($agentBill);
    }

    // 代理商分成
    public function merchantDiviend()
    {
        if ($this->balance < 1) {
            return false;
        }
        $merchant = $this->deviceGroup->merchant;
        $user = $merchant->user;
        $scale = 0.2;
        $policyRule = $merchant->policy_rule;
        if ($policyRule) {
            $scale = ($policyRule->scale / 10000);
        }
        $balance = intval($this->balance * $scale);
        // 给员工分成
        $balance = $this->staffDiviend($balance);
        if ($balance < 1) {
            return false;
        }
        $user->wallet->increment('balance', $balance);
        $this->balance = $this->balance - $balance;
        $userBill = [
            'origin_order_id'=>$this->order->id,
            'user_id' => $user->id,
            'fee' => $balance,
            'type' => 'INPUT',
            'channel' => $this->order->channel,
            'remark' => '订单分成'
        ];
        // 收入统计
        $profitReport = AdminProfitReport::firstOrCreate(['user_id'=>$user->id]);
        $profitReport->increment('amount',$balance);
        AdminBill::create($userBill);
    }

    public function distributorDiviend()
    {
        if ($this->balance < 1) {
            return false;
        }
        $memberGroups = $this->deviceGroup->members()
            ->where('role', 'DISTRIBUTOR')
            ->groupBy('policy_rule_id')
            ->get();
        foreach ($memberGroups as $members) {
            $policyRule = $members->first()->policy_rule;
            $scale = $policyRule ? ($policyRule->scale / 10000) : 0.2;
            $memberCount = $members->count();
            $balance = intval($this->balance * $scale / $memberCount);
            if ($balance >= 1) {
                foreach ($members as $member) {
                    $user = $member->user;
                    $user->wallet->increment('balance', $balance);
                    $this->balance = $this->balance - $balance;
                    $userBill = [
                        'origin_order_id'=>$this->order->id,
                        'user_id' => $user->id,
                        'fee' => $balance,
                        'type' => 'INPUT',
                        'channel' => $this->order->channel,
                        'remark' => '订单分成'
                    ];
                    // 收入统计
                    $profitReport = AdminProfitReport::firstOrCreate(['user_id'=>$user->id]);
                    $profitReport->increment('amount',$balance);
                    AdminBill::create($userBill);
                }
            } else {
                break;
            }
        }
        return $balance;
    }

    public function staffDiviend($balance)
    {
        if ($balance < 1) {
            return $balance;
        }
        $staffGroup = Group::where('device_group_id', $this->deviceGroup->id)->first();
        // 查询出分润员工并按策略分组
        $memberGroups = $staffGroup->member->groupBy('policy_rule_id');
        foreach ($memberGroups as $members) {
            $policyRule = $members->first()->policy_rule;
            $scale = $policyRule ? ($policyRule->scale / 10000) : 0.2;
            $memberCount = $members->count();
            $staffBalance = intval($balance * $scale / $memberCount);
            if ($staffBalance >= 1) {
                foreach ($members as $member) {
                    $user = $member->user;
                    $user->wallet->increment('balance', $staffBalance);
                    $balance = $balance - $staffBalance;
                    $userBill = [
                        'origin_order_id'=>$this->order->id,
                        'user_id' => $user->id,
                        'fee' => $staffBalance,
                        'type' => 'INPUT',
                        'channel' => $this->order->channel,
                        'remark' => '订单分成'
                    ];
                    $profitReport = AdminProfitReport::firstOrCreate(['user_id'=>$user->id]);
                    $profitReport->increment('amount',$staffBalance);
                    AdminBill::create($userBill);
                }
            } else {
                break;
            }
        }
        return $balance;
    }
}
